#include "CAN_Frame.h"


canU32_t crc16(canU8_t* data,int num,canU16_t crc)
{
    for (;num > 0;num--)
    {
        crc ^= (*data++ << 8);          // XOR byte into least sig. byte of crc
        for (int i = 0; i < 8; i++)
        {
            if ((crc & 0X8000) != 0)
                crc = (crc <<= 1)^CAN_CRC_DIVISOR;
            else                            // Else LSB is not set
                crc <<= 1;                  // Just shift right
        }
        crc &= 0XFFFF;
    }
    return crc;
}

canU16_t CAN_Frame::CRC15() {
    if(Size == Expanded)
    {
        canU64_t data[2] = {frame.dataU64[0],frame.dataU64[1] & 0X1001FFFFFFFF};
//        crc16();
    }
    else if(Size == Standard) canU64_t data[2] = {frame.dataU64[0],frame.dataU64[1] & 0X11FFFF};

    return 1;
}


void CAN_Frame::frameConfig(FrameType type,FrameSize size,canU32_t id){
    Type = type;
    Size = size;
    if(Size == Expanded)IDE = Recessive;
    else if(Size == Standard)IDE = Dominance;
    StdId = (id) & 0X7FFU;
    // 如果是扩展帧
    if(IDE == Recessive){
        ExtId = ((id) & 0X1FFFF800U) >> 11;
    }
    frameChanged = true;
}

void CAN_Frame::makeDataFrame(canU8_t* data,canU8_t len)
{
    canU8_t *p = frame.dataU8;
    SRR = Dominance;
    DLC = len;
    if(Size == Expanded)
    {
        if(frameChanged)
        {
            setBit(p,SOF,1,eSOF_MOVE);
            setBit(p,StdId,11,eStdId_MOVE);
            setBit(p,SRR,1,eSRR_MOVE);
            setBit(p,IDE,1,eIDE_MOVE);
            setBit(p,ExtId,18,eExtId_MOVE);
            setBit(p,RTR,1,eRTR_MOVE);
            setBit(p,r1,1,eR0_MOVE);
            setBit(p,r0,1,eR1_MOVE);

            setBit(p,DLC,4,eDLC_MOVE);
            for(int i = 0;i < DLC;i++)
                setBit(p,data[i],Data_LEN,eData0_MOVE + i * Data_LEN);

            CRC_15 = CRC15();
            setBit(p,CRC_15,15,eCRC_MOVE + DLC * Data_LEN);
            setBit(p,CRC_Q,1,eCRC_Q_MOVE + DLC * Data_LEN);
            setBit(p,ACK,1,eACK_MOVE + DLC * Data_LEN);
            setBit(p,ACK_Q,1,eACK_Q_MOVE + DLC * Data_LEN);
            setBit(p,_EOF,7,eEOF_MOVE + DLC * Data_LEN);
            frameChanged = false;
        }
        else
        {
            setBit(p,DLC,4,eDLC_MOVE);
            for(int i = 0;i < DLC;i++)
                setBit(p,data[i],Data_LEN,eData0_MOVE + i * Data_LEN);
            CRC_15 = CRC15();
            setBit(p,CRC_15,15,eCRC_MOVE + DLC * Data_LEN);
            setBit(p,CRC_Q,1,eCRC_Q_MOVE + DLC * Data_LEN);
            setBit(p,ACK,1,eACK_MOVE + DLC * Data_LEN);
            setBit(p,ACK_Q,1,eACK_Q_MOVE + DLC * Data_LEN);
            setBit(p,_EOF,7,eEOF_MOVE + DLC * Data_LEN);
        }
    }
    else if(Size == Standard){ // 标准帧格式
        if (frameChanged) {
            setBit(p, SOF, 1, sSOF_MOVE);
            setBit(p, StdId, 11, sStdId_MOVE);
            setBit(p, RTR, 1, sRTR_MOVE);
            setBit(p, IDE, 1, sIDE_MOVE);
            setBit(p, r0, 1, sR0_MOVE);
            setBit(p, DLC, 4, sDLC_MOVE);
            for (int i = 0; i < DLC; i++)
                setBit(p, data[i], Data_LEN, sData0_MOVE + i * Data_LEN);
            CRC_15 = CRC15();
            setBit(p, CRC_15, 15, sCRC_MOVE + DLC * Data_LEN);
            setBit(p, CRC_Q, 1, sCRC_Q_MOVE + DLC * Data_LEN);
            setBit(p, ACK, 1, sACK_MOVE + DLC * Data_LEN);
            setBit(p, ACK_Q, 1, sACK_Q_MOVE + DLC * Data_LEN);
            setBit(p, _EOF, 7, sEOF_MOVE + DLC * Data_LEN);
            frameChanged = false;
        }
        else
        {
            DLC = len;
            setBit(p, DLC, 4, sDLC_MOVE);
            for (int i = 0; i < DLC; i++)
                setBit(p, data[i], Data_LEN, sData0_MOVE + i * Data_LEN);
            CRC_15 = CRC15();
            setBit(p, CRC_15, 15, sCRC_MOVE + DLC * Data_LEN);
            setBit(p, CRC_Q, 1, sCRC_Q_MOVE + DLC * Data_LEN);
            setBit(p, ACK, 1, sACK_MOVE + DLC * Data_LEN);
            setBit(p, ACK_Q, 1, sACK_Q_MOVE + DLC * Data_LEN);
            setBit(p, _EOF, 7, sEOF_MOVE + DLC * Data_LEN);
        }
    }
}

void CAN_Frame::makeRemoteFrame(canU8_t lenNeed)
{
    canU8_t *p = frame.dataU8;
    RTR = Recessive;
    SRR = Recessive;
    DLC = lenNeed;

    if(Size == Expanded)
    {
        setBit(p,SOF,1,eSOF_MOVE);
        setBit(p,StdId,11,eStdId_MOVE);
        setBit(p,SRR,1,eSRR_MOVE);
        setBit(p,IDE,1,eIDE_MOVE);
        setBit(p,ExtId,18,eExtId_MOVE);
        setBit(p,RTR,1,eRTR_MOVE);
        setBit(p,r1,1,eR0_MOVE);
        setBit(p,r0,1,eR1_MOVE);
        setBit(p,DLC,4,eDLC_MOVE);
        for(int i = 0;i < DLC;i++)
            setBit(p,0,Data_LEN,eData0_MOVE + i * Data_LEN);
        CRC_15 = CRC15();
        setBit(p,CRC_15,15,eCRC_MOVE + DLC * Data_LEN);
        setBit(p,CRC_Q,1,eCRC_Q_MOVE + DLC * Data_LEN);
        setBit(p,ACK,1,eACK_MOVE + DLC * Data_LEN);
        setBit(p,ACK_Q,1,eACK_Q_MOVE + DLC * Data_LEN);
        setBit(p,_EOF,7,eEOF_MOVE + DLC * Data_LEN);
    }
    else if(Size == Standard)
    {
        setBit(p, SOF, 1, sSOF_MOVE);
        setBit(p, StdId, 11, sStdId_MOVE);
        setBit(p, RTR, 1, sRTR_MOVE);
        setBit(p, IDE, 1, sIDE_MOVE);
        setBit(p, r0, 1, sR0_MOVE);
        setBit(p, DLC, 4, sDLC_MOVE);
        for (int i = 0; i < DLC; i++)
            setBit(p, 0, Data_LEN, sData0_MOVE + i * Data_LEN);
        CRC_15 = CRC15();
        setBit(p, CRC_15, 15, sCRC_MOVE + DLC * Data_LEN);
        setBit(p, CRC_Q, 1, sCRC_Q_MOVE + DLC * Data_LEN);
        setBit(p, ACK, 1, sACK_MOVE + DLC * Data_LEN);
        setBit(p, ACK_Q, 1, sACK_Q_MOVE + DLC * Data_LEN);
        setBit(p, _EOF, 7, sEOF_MOVE + DLC * Data_LEN);
    }

}

void CAN_Frame::makeErrorFrame()
{

}

void CAN_Frame::makeOverloadFrame()
{

}

void CAN_Frame::makeBetweenFrame()
{

}


